/*
    1、数据缓冲区类

*/
#ifndef __MY_BUFFER_H__
#define __MY_BUFFER_H__
#include <string>
#include <vector>
#include <cassert>
using namespace std;
namespace LogBuffer
{
    const static int DDEFAULT_BUFFER_MAX = 1 * 1024 * 1024;
    const static int THRESHOLD_BUFFER_MAX = 10 * 1024 * 1024; // 设置成倍扩容阈值为100M;
    const static int LINEAR_BUFFER_MAX = 1 * 1024 * 1024;     // 线性增长大小
    class Buffer
    {
    public:
        Buffer() : _buffer(DDEFAULT_BUFFER_MAX), reader_index(0), writer_index(0) {}
        // 数据写入缓冲区
        void push(const char *Data, size_t len)
        {
            // 判断当前空间容量是否可以进行写入
            /*
                扩容:小于阈值，成倍扩容，大于阈值，线性扩容---->极限性能测试
             */
            EnsureEnoughSize(len);
            // 将数据拷贝到缓冲区
            copy(Data, Data + len, &_buffer[writer_index]);
            // 将当前可写入位置向后偏移
            MoveWriter(len);
        }
        // 返回可读数据的起始地址
        const char *begin()
        {
            return &_buffer[reader_index];
        }
        // 返回可读数据的长度
        size_t readAbleSize()
        {
            return writer_index - reader_index;
        }
        // 返回可写数据的长度
        size_t writeAbleSize()
        {
            return _buffer.size() - writer_index;
        }
        // 对读指针向后移动
        void MoveReader(size_t len)
        {
            assert(len <= readAbleSize());
            reader_index += len;
        }
        // 交换缓冲区
        void swap(Buffer &buffer)
        {
            _buffer.swap(buffer._buffer);
            std::swap(reader_index, buffer.reader_index);
            std::swap(writer_index, buffer.writer_index);
        }
        // 重置缓冲区
        void reset()
        {
            reader_index = 0;
            writer_index = 0;
        }
        // 判断缓冲区是否为空
        bool empty()
        {
            return reader_index == writer_index;
        }

    private:
        // 对写指针向后移动
        void MoveWriter(size_t len)
        {
            assert(len <= writeAbleSize());
            writer_index += len;
        }
        void EnsureEnoughSize(size_t len) // 判断是否需要扩容
        {
            if (len <= writeAbleSize())
                return;
            int newsize = 0;
            if (_buffer.size() < THRESHOLD_BUFFER_MAX)
            {
                newsize = _buffer.size() * 2 + len;
            }
            else
                newsize = _buffer.size() + LINEAR_BUFFER_MAX + len;
            _buffer.resize(newsize);
        }

    private:
        vector<char> _buffer; // 存放格式化后的日志字符串
        size_t reader_index;  // 当前可读数据的指针
        size_t writer_index;  // 当前可写数据的指针
    };
}

#endif